/*
 * Copyright (C) 2017 Pingan, Inc. All Rights Reserved.
 */

package com.pingan.haofang.searchcloud.web.project.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.collect.Lists;
import com.pingan.haofang.framework.common.functional.lang.control.bean.BeanCopy;
import com.pingan.haofang.gov.sm.account.common.SessionVisitor;
import com.pingan.haofang.gov.sm.account.common.UserThreadContext;
import com.pingan.haofang.gov.sm.account.entity.enums.YesNoEnum;
import com.pingan.haofang.searchcloud.common.constants.WebConstants;
import com.pingan.haofang.searchcloud.common.exception.AccessForbbidenException;
import com.pingan.haofang.searchcloud.common.exception.NotFoundException;
import com.pingan.haofang.searchcloud.user.constant.ProjectConstants;
import com.pingan.haofang.searchcloud.user.constant.ProjectStatus;
import com.pingan.haofang.searchcloud.user.dto.ProjectQueryDto;
import com.pingan.haofang.searchcloud.user.dto.SearchProjectDto;
import com.pingan.haofang.searchcloud.user.dto.SearchUserDto;
import com.pingan.haofang.searchcloud.user.service.SearchProjectService;
import com.pingan.haofang.searchcloud.user.service.SearchUserService;
import com.pingan.haofang.searchcloud.web.project.form.ProjectForm;
import com.pingan.haofang.searchcloud.web.project.form.ProjectIdForm;
import com.pingan.haofang.searchcloud.web.project.form.ProjectNotifyForm;
import com.pingan.haofang.searchcloud.web.project.form.ProjectQueryForm;
import com.pingan.haofang.searchcloud.web.project.vo.ProjectVo;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 项目Controller
 *
 * @author zhangbi617
 * @date 08/05/2017
 */
@RestController
@RequestMapping(value = WebConstants.WEB_PREFIX + "/project")
@Api(tags = "Project.Manage", description = "项目接口")
public class ProjectController {

    @Autowired
    private SearchProjectService searchProjectService;

    @Autowired
    private SearchUserService searchUserService;

    /**
     * 读取项目列表
     *
     * @return
     */
    @ApiOperation(value = "创建或者更新项目")
    @PostMapping(value = "")
    public void createOrUpdateProject(@RequestBody ProjectForm form,
                                      HttpServletRequest request) {
        SearchProjectDto searchProjectDto;
        if (form.getId() != null && form.getId() != 0) {
            // 修改
            searchProjectDto = searchProjectService.get(form.getId());
            if (searchProjectDto == null) {
                throw new NotFoundException("project not found");
            }
            searchProjectDto.setProjectName(form.getProjectName());
            searchProjectDto.setIntroduction(form.getIntroduction());
            searchProjectDto.setMailTo(form.getMailTo());
        } else {
            // 创建
            searchProjectDto = new SearchProjectDto();
            // 默认状态
            searchProjectDto.setProjectCode(form.getProjectCode());
            searchProjectDto.setProjectName(form.getProjectName());
            searchProjectDto.setIntroduction(form.getIntroduction());
            searchProjectDto.setMasterId(UserThreadContext.getSessionVisitor().getAccountId());
            searchProjectDto.setStatus(ProjectStatus.NORMAL.getId());
            searchProjectDto.setToken(RandomStringUtils.random(ProjectConstants.TOKEN_LENGTH,
                    "abcdefghijklmnopqrstuvwxyz"));
            searchProjectDto.setMailTo(form.getMailTo());
        }

        // 发送邮件给响应用户
        Long projectId = searchProjectService.update(searchProjectDto);
        final SearchUserDto searchUser = searchUserService.getUserById(searchProjectDto.getMasterId());
        searchProjectService.sendTokenNotify(projectId,
                Lists.newArrayList(searchUser.getEmail()), request.getServerName());
    }

    /**
     * 读取项目列表
     */
    @ApiOperation(value = "获取项目列表")
    @GetMapping(value = "")
    public List<ProjectVo> getProjects(ProjectQueryForm form) {
        SessionVisitor sessionVisitor = UserThreadContext.getSessionVisitor();
        
        ProjectQueryDto queryDto = new ProjectQueryDto();
        // 这里只有普通用户看自己的
        if (sessionVisitor.getSessionViewDTO().getIsRoot() == YesNoEnum.NO.getValue()) {
            queryDto.setMasterId(sessionVisitor.getAccountId());
        }
        queryDto.setProjectCode(form.getProjectCode());
        queryDto.setProjectName(form.getProjectName());
        queryDto.setStatus(form.getStatus());

        // 获取所有项目
        List<SearchProjectDto> projectDTOs = searchProjectService.getList(queryDto);

        Set<Long> userIds = projectDTOs.stream().map(SearchProjectDto::getMasterId).collect(Collectors.toSet());

        Map<Long, SearchUserDto> searchUserDtoMap = searchUserService.getUserMapByIds(userIds);

        List<ProjectVo> projectVos = projectDTOs.stream()
                .map(dto -> BeanCopy.of(dto, new ProjectVo())
                        .copy(BeanUtils::copyProperties)
                        .set(vo -> vo.setMasterUserName(searchUserDtoMap.get(dto.getMasterId()).getUserName()))
                        .get())
                .collect(Collectors.toList());

        return projectVos;
    }

    /**
     * 读取一个项目
     */
    @ApiOperation(value = "读取一个项目")
    @GetMapping(value = "{projectId}")
    public ProjectVo getProject(
            @ModelAttribute ProjectIdForm form) {
        SearchProjectDto searchProjectDto = searchProjectService.get(form.getProjectId());

        if (searchProjectDto == null) {
            return null;
        }

        final SearchUserDto searchUser = searchUserService.getUserById(searchProjectDto.getMasterId());

        return BeanCopy.of(searchProjectDto, new ProjectVo())
                .copy(BeanUtils::copyProperties)
                .set(vo -> vo.setMasterUserName(searchUser.getUserName()))
                .get();
    }

    /**
     * 通知一个项目信息
     */
    @ApiOperation(value = "邮件通知项目token等信息")
    @PutMapping("tokens")
    public void sendProjectNotify(@RequestBody ProjectNotifyForm form,
                                  HttpServletRequest request) {
        SearchProjectDto searchProjectDto = searchProjectService.get(form.getProjectId());

        SessionVisitor sessionVisitor = UserThreadContext.getSessionVisitor();
        
        // 只有管理员和负责人有权限
        if (sessionVisitor.getSessionViewDTO().getIsRoot() == YesNoEnum.NO.getValue() &&
        		!Objects.equals(searchProjectDto.getMasterId(), sessionVisitor.getAccountId())) {
        	throw new AccessForbbidenException("user.access.forbidden");
        }
        
        List<String> emailToAddresses = (form.getNotifyEmails() == null)
                ? new ArrayList<>() : form.getNotifyEmails();

        final SearchUserDto searchUser = searchUserService.getUserById(searchProjectDto.getMasterId());

        emailToAddresses.add(searchUser.getEmail());

        searchProjectService.sendTokenNotify(form.getProjectId(),
                emailToAddresses, request.getServerName());

    }
}
